var fix_grid_width;

$.fn.fixgrid = function (opt,params) {
    if( opt == 'loadData' ){
        fixGridLoadData($(this),params);
        //auto height
        $(this).height($(this).find('.top-left').height()+$(this).find('.ctx-right').height());
        return;
    }else if( opt == 'showColumns' ){
        fixGridShowColumns($(this),params);
        return;
    }
    var options = {};
    $.extend(options,opt);
    var grid = $(this);
    initGrid(options,grid);

    createTopLeft(options,grid);
    createTopRight(options,grid);
    createCtxLeft(options,grid);
    createCtxRight(options,grid);

    fixBodyEvent(grid);

    grid.height(grid.find('.top-left').height());
};

function initGrid(options,grid) {
    grid.data({options:options});
    grid.addClass('vui-fix-grid');
    if( options.width ){
        fix_grid_width = options.width;
        grid.css({"margin":"0px","margin":"0px 15px"});
    }else{
        fix_grid_width = $(document.body).width()-30;    
    }
    grid.width(fix_grid_width);
}

function createTopLeft(options,grid) {
    var fixColumns = options.columns[0];
    var topLeft = $('<div class="top-left"></div>').width(calcLeftWidth(options));
    var table = $('<div class="vui-table"></div>');
    var head = $('<div class="vui-table-head"></div>');

    for( var i=0 ; i<fixColumns.length ; i++ ){
        var cell = $('<div class="vui-table-cell">'+fixColumns[i].title+'</div>');
        cell.width(fixColumns[i].width);
        head.append(cell);
    }
    table.append(head);
    topLeft.append(table);
    grid.append(topLeft);
}

function createTopRight(options,grid) {
    var ctxColumns = options.columns[1];
    var leftWidth = calcLeftWidth(options);
    var topRight = $('<div class="top-right"></div>').width( fix_grid_width - leftWidth );
    topRight.css({"left":leftWidth+"px"});
    var topRightInner = $('<div class="top-right-inner"></div>');
    var table = $('<div class="vui-table"></div>');
    var head = $('<div class="vui-table-head"></div>');
    for( var i=0 ; i<ctxColumns.length ; i++ ){
        var cell = $('<div class="vui-table-cell" field="'+ctxColumns[i].field+'">'+ctxColumns[i].title+'</div>');
        if(i==0)cell.css({"border-left":"none"});
        cell.width(ctxColumns[i].width);
        if( ctxColumns[i].hide ) cell.hide();
        head.append(cell);
    }
    table.append(head);
    topRightInner.append(table);
    topRight.append(topRightInner);
    grid.append(topRight);
}

function fixGridShowColumns(grid,columns){
    for(var i=0 ; i<columns.length ; i++){
        grid.find('.ctx-right .vui-table .vui-table-cell[field="'+columns[i]+'"]').show();
        grid.find('.top-right .vui-table .vui-table-cell[field="'+columns[i]+'"]').show();
    }
}

function fixGridLoadData(grid,data) {
    var options = grid.data().options;
    loadRows(data,options.columns[0],grid.find('.ctx-left .vui-table'),'left');
    loadRows(data,options.columns[1],grid.find('.ctx-right .vui-table'),'right');
}

function fixBodyEvent(grid) {
    grid.find('.ctx-right').scroll(function (e) {
        grid.find('.top-right-inner').scrollLeft($(this).scrollLeft());
    });
}

function createCtxLeft(options,grid) {
    var options = grid.data().options;

    var ctx = $('<div class="ctx-left"></div>');
    var leftWidth = calcLeftWidth(options);
    ctx.width(leftWidth);

    var table = $('<div class="vui-table"></div>');
    /*var rows = data.rows;
    loadRows(rows,columns,table,'left');*/

    ctx.append(table);
    grid.append(ctx);

}

function createCtxRight(options,grid) {
    var options = grid.data().options;

    var ctx = $('<div class="ctx-right"></div>');
    var leftWidth = calcLeftWidth(options);
    ctx.width(fix_grid_width - leftWidth );
    ctx.css({"left":leftWidth+"px"});
    if( options.noscroll )ctx.css({"overflow-x":"auto"});

    var table = $('<div class="vui-table"></div>');

    ctx.append(table);
    grid.append(ctx);
}

function loadRows(data,columns,table,role) {
    var rows = data.rows;
    for( var i=0 ; i<rows.length ; i++ ){
        var row = $('<div class="vui-table-row"></div>');
        for( var j=0 ; j<columns.length ; j++ ){
            var cell = $('<div class="vui-table-cell"></div>');
            cell.append(getCellValue(data.bottom,rows[i],columns[j]));
            cell.width(columns[j].width);
            cell.data({row:rows[i],column:columns[j]});
            cell.click(cellClickEvent);
            cell.attr('editor',columns[j].editor);
            cell.attr('field',columns[j].field);
            setCellStyle(cell,columns[j]);
            setRightHide(cell,columns[j]);
            setRightBorder(cell,i,j,columns,role);
            row.append(cell);
        }
        if( data.bottom ){
            row.attr('bottom','1');
            table.append(row);
        }else{
            var bottom = table.find('.vui-table-row[bottom="1"]');
            if( bottom.length == 0 ){
                table.append(row);
            }else{
                bottom.before(row);
            }
        }
    }
}

function setCellStyle(cell,column) {
    if( column.editor == 'decimal' || column.editor == 'number' ){
        cell.css({"text-align":"right","padding-right":"15px"});
    }
    if( column.align ){
        var data = {"text-align":column.align};
        data['padding-'+column.align] = "15px";
        cell.css(data);
    }
}

function setRightHide(cell,column) {
    if( column.hide )cell.hide();
}

function setRightBorder(cell,i,j,columns,role) {
    if(role=='left'){
        return;
    }
    if( i==0){
        cell.css({"border-top":"none"});
    }
    if(j==columns.length-1){
        cell.css({"border-right":"none"});
    }
    if(j==0){
        cell.css({"border-left":"none"});
    }
}

function getCellValue(bottom,row,column) {
    if(bottom){
        return '';
    }

    var value;
    if( column.formatter ){
        value = column.formatter(row);
    }else{
        value = row[column.field];
    }

    if( value == null || value == undefined ){
        value = "";
    }

    return value;
}

function calcLeftWidth(options) {
    var columns = options.columns[0];
    var width = 1;
    for( var i=0 ; i<columns.length ; i++ ){
        width += columns[i].width;
    }
    return width;
}

function cellClickEvent(e) {
    e.stopPropagation();
    editAfterEvent({target:{className:'before'}});

    var cellData = $(this).data();

    if( cellData.column.editBefore && !cellData.column.editBefore($(this)) ){
        return;
    }

    var editor = cellData.column.editor;
    var ele = null;
    if( editor == 'text' || editor == 'decimal' || editor == 'number' ){
        ele = createInputEditor($(this),editor);
    }else if( editor == 'search' ){
        createSearchEditor($(this),cellData.column);
    }else if( editor == 'date' ){
        createDateEditor($(this),cellData.column);
    }else if( editor == 'combobox' ){
        createComboEditor($(this),cellData.row,cellData.column);
    }

    if( ele != null ){
        $(this).empty().append(ele);
        ele.focus().select();
    }
}
function createComboEditor(_this,row,column) {
    if( _this.find('input').length > 0 ){
        return;
    }
    var id = 'combo'+ new Date().getTime();
    var combo = $('<div role="combobox" id="'+id+'"></div>');
    _this.empty().append(combo);

    column.getData(_this,function (data) {
        $('#'+id).combobox({
            width:_this.width(),
            data:data,
            name:id,
            valueField:'id',
            textField:'name'
        });

        if(column.comboboxData){
            var comboboxData = column.comboboxData(_this);
            if( comboboxData && comboboxData.value ){
                $('#'+id).combobox('setValue',comboboxData.value,comboboxData.text);
            }

        }


    });
}

function createDateEditor(_this,column) {
    if( _this.find('.input-date').length > 0 ){
        return null;
    }

    var value = $.trim(_this.html());

    var input = $('<input type="text" class="input-date"/>');
    input.width(_this.width()-2);
    input.click(function (e) {
        e.stopPropagation();
    });
    _this.empty().append(input);
    laydate.render({
        elem: '.input-date',
        value:value.length>0?value:app.getServerDate()
    });
}

function createSearchEditor(_this,column) {
    if( _this.find('input').length > 0 ){
        return;
    }

    var _thisHisHtml = $.trim(_this.html());

    var searchId = "search"+new Date().getTime();
    var search = $('<div role="search" id="'+searchId+'"></div>');
    _this.empty().append(search);
    $('#'+searchId).search({
        name:searchId,
        placeholder:column.placeholder,
        width:_this.width(),
        click:function () {
            if(column.click)column.click(searchId);
        },
        change:function () {
            if(column.change)column.change(searchId);
        }
    });

    if(column.searchData){
        var searchData = column.searchData(_this,_thisHisHtml);
        if(searchData){
            $('#'+searchId).search('setValue',searchData.id,searchData.name);
        }
    }

}

function createInputEditor(_this,editor) {
    if( _this.find('.input-edit').length > 0 ){
        return null;
    }

    var input = $('<input type="text" e="1" class="input-edit"/>');
    var value = $.trim(_this.html());
    input.width(_this.width()-2).val(value).data({"editor":editor,"value":value});

    input.blur(function () {
        inputEditorEvent($(this));
    }).keydown(function(e){
        if( e.keyCode == 13 )inputEditorEvent($(this));
    });

    return input;
}

function inputEditorEvent(_this) {
    if(!_this)_this = $(this);
    var editor = _this.data("editor");
    var value = _this.val();

    if( editor == 'decimal' ){
        var reg = /^(-?\d+)(\.\d{0,2})?$/;
        if( !reg.test(value) ){
            value = _this.data("value");
        }
    }else if( editor == 'number' ){
        var reg = /^(-?\d+)$/;
        if( !reg.test(value) ){
            value = _this.data("value");
        }
    }
    var cell = _this.parent();
    cell.html(value);
    if(cell.data().column.editAfter)cell.data().column.editAfter(cell);
}